/* Copyright 2011 Tobias Marschall, Email: tm@cwi.nl 
 * 
 * This file is part of string-cover.
 *
 * string-cover is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * string-cover is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with string-cover.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <iostream>
#include <cassert>
#include <boost/tr1/unordered_map.hpp>

#include "SubstringStore.h"

using namespace std;
using namespace std::tr1;

SubstringStore::SubstringStore(const std::vector<std::string>* strings) {
	this->strings = strings;
	typedef	unordered_map<string,size_t> umap_t;
	umap_t substring_to_index;
	interval_to_index = new size_t**[strings->size()];
	for (size_t string_nr=0; string_nr<strings->size(); ++string_nr) {
		const string& s = strings->at(string_nr);
		interval_to_index[string_nr] = new size_t*[s.size()];
		for (size_t start=0; start<s.size(); ++start) {
			interval_to_index[string_nr][start] = new size_t[s.size()-start];
			for (size_t length=1; length<=s.size()-start; ++length) {
				string substring = s.substr(start, length);
				umap_t::const_iterator i = substring_to_index.find(substring);
				if (i == substring_to_index.end()) {
					interval_t interval;
					interval.index = string_nr;
					interval.start = start;
					interval.length = length;
					index_to_interval.push_back(interval);
					index_to_count.push_back(1);
					interval_to_index[string_nr][start][length-1] = index_to_interval.size()-1;
					substring_to_index[substring] = index_to_interval.size()-1;
				} else {
					interval_to_index[string_nr][start][length-1] = i->second;
					index_to_count[i->second] += 1;
				}
			}
		}
	}
}

SubstringStore::~SubstringStore() {
	for (size_t string_nr=0; string_nr<strings->size(); ++string_nr) {
		const string& s = strings->at(string_nr);
		for (size_t start=0; start<s.size(); ++start) {
			delete[] interval_to_index[string_nr][start];
		}
		delete[] interval_to_index[string_nr];
	}
	delete[] interval_to_index;
}

std::string SubstringStore::getSubstring(size_t index) const {
	assert(index < index_to_interval.size());
	const interval_t& interval = index_to_interval[index];
	const string& s = strings->at(interval.index);
	return s.substr(interval.start, interval.length);
}

size_t SubstringStore::size() const {
	return index_to_interval.size();
}

size_t SubstringStore::getIndex(size_t string_nr, size_t start_pos, size_t end_pos) const {
	assert(string_nr < strings->size());
	assert(start_pos<end_pos);
	assert(end_pos<=strings->at(string_nr).size());
	size_t length = end_pos - start_pos;
	return interval_to_index[string_nr][start_pos][length-1];
}

size_t SubstringStore::getCount(size_t index) const {
	assert(index < index_to_count.size());
	return index_to_count[index];
}


